package com.kuzan.autocloud.secutiry;

import com.kuzan.autocloud.common.Result;
import com.kuzan.autocloud.common.model.organization.Person;
import com.kuzan.autocloud.common.repository.organization.PersonRepository;
import com.kuzan.autocloud.common.util.UuidUtil;
import com.kuzan.autocloud.secutiry.helper.JwtHelper;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * <p>Description: </p>
 *
 * @author kuzank 2019/12/1
 */
@Service
public class AccountVerifyService {

    @Value("${token.expire.time}")
    private long tokenExpireTime;
    @Value("${refresh.token.expire.time}")
    private long refreshTokenExpireTime;
    @Value("${jwt.refresh.token.key.format}")
    private String jwtRefreshTokenKeyFormat;

    @Autowired
    private JwtHelper jwtHelper;
    @Autowired
    private PersonRepository personRepository;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private BCryptPasswordEncoder bCryptPasswordEncoder;


    public Result verify(Map<String, String> param) {

        if (param == null) {
            return Result.oflost("账号密码为空！", 201);
        }

        String userName = param.get("username");
        String password = param.get("password");

        if (StringUtils.isEmpty(userName)) {
            return Result.oflost("账号为空！", 201);
        }

        if (StringUtils.isEmpty(password)) {
            return Result.oflost("密码为空！", 201);
        }

        try {

            Optional<Person> personOptional = personRepository.findByUsername(userName);
            if (!personOptional.isPresent()) {
                return Result.oflost("账号不存在！", 201);
            }

            Person person = personOptional.get();
            // 判断密码是否正确
            if (!bCryptPasswordEncoder.matches(password, person.getPassword())) {
                return Result.oflost("密码错误！", 201);
            }

            // 生成 JWT
            String token = jwtHelper.buildJWT(person);
            // 生成 refreshToken
            String refreshToken = UuidUtil.randomUUID();
            // 保存 refreshToken 至 redis，使用 hash 结构保存使用中的 token 以及用户标识
            String refreshTokenKey = String.format(jwtRefreshTokenKeyFormat, refreshToken);

            stringRedisTemplate.opsForHash().put(refreshTokenKey, "token", token);
            stringRedisTemplate.opsForHash().put(refreshTokenKey, "userName", person.getId());

            // refreshToken 设置过期时间
            stringRedisTemplate.expire(refreshTokenKey, refreshTokenExpireTime, TimeUnit.MILLISECONDS);

            return Result.ofsuccess(new HashMap<String, Object>() {{
                put("token", token);
                put("refreshToken", refreshToken);
                put("name", person.getTitle());
                put("id", person.getId());
            }});

        } catch (Exception e) {
            e.printStackTrace();
            return Result.oflost("登陆失败！", 201);
        }
    }
}
